package com.zx.map.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zx.map.dao.mapper.ActiveRedpacketMapper;
import com.zx.map.dao.mapper.RedpacketMapper;
import com.zx.map.dao.model.ActiveRedpacket;
import com.zx.map.dao.model.Redpacket;
import com.zx.map.dao.model.RedpacketExample;
import com.zx.map.service.RedpacketService;
import com.zx.map.utils.CommonResponseUtils;
import com.zx.map.utils.SUConstants;
import com.zx.platform.utils.PmpUtils;

@Component("redpacketService")
public class RedpacketServiceImpl implements RedpacketService {

	@Autowired
	private RedpacketMapper mapper ;
	
	@Autowired
	private ActiveRedpacketMapper amapper;
	@Override
	public int add(Redpacket redpacket)  throws DataAccessException{
		
		Map<String, Date> hms = PmpUtils.dateAddHms(redpacket.getBeginDatetime(), redpacket.getEndDatetime());
		redpacket.setBeginDatetime(hms.get("beginDatetime"));
		redpacket.setEndDatetime(hms.get("endDatetime"));
		
		if(this.checkStartAndEndDate(redpacket.getBeginDatetime(), redpacket.getEndDatetime())) {
			return SUConstants.ILLEGAL_DATE;
		}
		if(hasActiveRedpacket(redpacket.getMerchantId())) {
			return mapper.insertSelective(redpacket);
		}
		return SUConstants.REDPACKET_IS_PROCESSING;
	}

	@Override
	public int update(Redpacket redpacket)  throws DataAccessException{
		
		Map<String, Date> hms = PmpUtils.dateAddHms(redpacket.getBeginDatetime(), redpacket.getEndDatetime());
		redpacket.setBeginDatetime(hms.get("beginDatetime"));
		redpacket.setEndDatetime(hms.get("endDatetime"));
		if(this.checkStartAndEndDate(redpacket.getBeginDatetime(), redpacket.getEndDatetime())) {
			return SUConstants.ILLEGAL_DATE;
		}
		mapper.updateByPrimaryKeySelective(redpacket);
		return SUConstants.DEAL_SUCCESS;
	}

	@Override
	public void delete(int redpacketId)  throws DataAccessException{
		mapper.setDelStatu(redpacketId);

	}

	@Override
	public List<Redpacket> query(String merchantId)  throws DataAccessException{
		RedpacketExample example = new RedpacketExample();
		RedpacketExample.Criteria criteria = example.createCriteria();
		if(StringUtils.isNotBlank(merchantId)) {
			criteria.andMerchantIdEqualTo(merchantId);
		}
		return mapper.selectByExample(example);
	}

	@Override
	public Redpacket info(int redpacketId)  throws DataAccessException{
		int oldVipNum = this.countOldVipNum(redpacketId);
		Redpacket redpacket = mapper.selectByPrimaryKey(redpacketId);
		redpacket.setOldVipNum(oldVipNum);
		return redpacket;
	}

	/**
	 * 分页查询红包活动
	 */
	@Override
	public List<Redpacket> queryByLimit(Map condition)  throws DataAccessException{
		RedpacketExample example = new RedpacketExample();
		RedpacketExample.Criteria criteria = example.createCriteria();
		
		criteria.andDelStatuEqualTo(false);
		//供应商信息
		if(condition.containsKey("merchantId") && StringUtils.isNotBlank((String)condition.get("merchantId"))) {
			criteria.andMerchantIdEqualTo((String)condition.get("merchantId"));
		}
		//红包活动状态：1:进行中，2:已结束
		if(condition.containsKey("status") && StringUtils.isNotEmpty((String)condition.get("status"))) {
			String status = (String)condition.get("status");
			switch(status) {
			case SUConstants.REDPACKET_STATU_VALID:
				criteria.andEndDatetimeGreaterThan(new Date());
				break;
			case SUConstants.REDPACKET_STATU_INVALID:
				criteria.andEndDatetimeLessThan(new Date());
				break;
			default:
				criteria.andEndDatetimeGreaterThan(new Date());
				break;
			}
		}
		int pageBegin = SUConstants.PAGE_DEFAULT_START; //业码
		int pageSize = SUConstants.PAGE_COUNT; //每页的大小
		if(condition.containsKey("pageNum") && condition.containsKey("pageSize")) {
			pageBegin = Integer.parseInt(StringUtils.isNotEmpty((String)condition.get("pageNum")) ? (String)condition.get("pageNum") : "0");
			pageSize = Integer.parseInt(StringUtils.isNotEmpty((String)condition.get("pageSize")) ? (String)condition.get("pageSize") : "10");	
		}
		List<Redpacket> result = mapper.getPageByModel( pageSize,pageSize*(pageBegin-1), example);
		result.stream().forEach(e->{
			e.setOldVipNum(this.countOldVipNum(e.getRedpacketId()));
		});
		return result;
	}

	@Override
	public boolean hasActiveRedpacket(String merchantId)  throws DataAccessException{
		int count = mapper.hasActiveRedpacket(merchantId);
		return count == 0;
	}

	@Override
	public Redpacket queryRedpacketByMerchantId(String merchantId, BigDecimal totalMoney)  throws DataAccessException{
		return mapper.queryRedpacketByMerchant(merchantId, totalMoney);
	}

	@Override
	public int increaseJoinNum(Integer redpacketId)  throws DataAccessException{
		return mapper.increaseJoinNum(redpacketId);
	}

	@Override
	public int countOldVipNum(Integer redpacketId)  throws DataAccessException{
		return mapper.countOldVipNum(redpacketId);
	}

	@Override
	public int dealRedpacketUsed(Map<String, Object>condition)  throws DataAccessException{
		ActiveRedpacket activeRedpacket = mapper.selectUseRedpacket((String)condition.get("merchantId"), (String)condition.get("userId"), new BigDecimal((String)condition.get("consumeMoney")));
		if(Objects.isNull(activeRedpacket)) {
			throw new RuntimeException("当前红包不可用！");
		}
		return mapper.dealRedpacketUsed(activeRedpacket.getId(),  new BigDecimal((String)condition.get("consumeMoney")));
	}

	@Override
	public ActiveRedpacket selectUseRedpacket(String merchantId, String userId, BigDecimal consumeMoney)  throws DataAccessException{
		return mapper.selectUseRedpacket(merchantId, userId, consumeMoney);
	}

	@Override
	public boolean checkStartAndEndDate(Date startDate, Date endDate)  throws DataAccessException{
		Date today = PmpUtils.strToDate(PmpUtils.dateToString(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
		return startDate.before(today) || endDate.before(today);
	}

	@Override
	public Map<String, Object> noticeInfo(String merchantId, int pageNum, int pageSize)  throws DataAccessException,NullPointerException{
		Objects.requireNonNull(pageNum);
		Objects.requireNonNull(pageSize);
		RedpacketExample example = new RedpacketExample();
		RedpacketExample.Criteria criteria = example.createCriteria();
		criteria.andDelStatuEqualTo(false);
		if(StringUtils.isNoneEmpty(merchantId)) {
			criteria.andMerchantIdEqualTo(merchantId);
		}
		
		long count = mapper.getRedpacketNums(example);
		BigDecimal totalMoney = mapper.getTotalActiveMoney(example);
		example.setOrderByClause("create_datetime desc");
		PageHelper.startPage(pageNum, pageSize);
		List<Redpacket> list = mapper.selectByExample(example);
		PageInfo<Redpacket> pageInfo = new PageInfo<Redpacket>(list);
		pageInfo.getList().stream().forEach(e->{
			e.setOldVipNum(this.countOldVipNum(e.getRedpacketId()));
		});
		
		Map<String, Object> result = new HashMap<>();
		result.put("status", !hasActiveRedpacket(merchantId));
		result.put("count", count);
		result.put("totalMoney", totalMoney);
		result.put("list", pageInfo.getList());
		return result;
	}

	@Override
	public BigDecimal getMoney(String merchantId, BigDecimal useMoney) throws DataAccessException {
		RedpacketExample example = new RedpacketExample();
		RedpacketExample.Criteria criteria = example.createCriteria();
		if(StringUtils.isEmpty(merchantId)) {
			throw new RuntimeException("登录超时，请重新登录!");
		}else {
			criteria.andMerchantIdEqualTo(merchantId);
			criteria.andBeginDatetimeGreaterThanOrEqualTo(new Date());
			criteria.andEndDatetimeLessThanOrEqualTo(new Date());
			criteria.andDelStatuEqualTo(false);
			criteria.andUseMoneyGreaterThanOrEqualTo(useMoney);
			List<Redpacket> list = mapper.selectByExample(example);
			if(list.isEmpty()) {
				return BigDecimal.ZERO;
			}else if(Objects.isNull(list.get(0).getMoney())) {
				return BigDecimal.ZERO;
			}else {
				return list.get(0).getMoney();
			}
		}
		
	}

}
